package com.gzc.just.play.last.war.centralserver.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 匹配服务
 * 负责处理玩家匹配逻辑
 */
@Service("central-matchmakingService")
public class MatchmakingService {
    private static final Logger logger = LoggerFactory.getLogger(MatchmakingService.class);
    
    // 等待匹配的玩家队列
    private final Map<Long, PlayerQueueInfo> waitingPlayers = new ConcurrentHashMap<>();
    
    /**
     * 添加玩家到匹配队列
     */
    public void addPlayerToQueue(long playerId, String playerName, int level) {
        PlayerQueueInfo playerInfo = new PlayerQueueInfo();
        playerInfo.setPlayerId(playerId);
        playerInfo.setPlayerName(playerName);
        playerInfo.setLevel(level);
        playerInfo.setQueueTime(System.currentTimeMillis());
        
        waitingPlayers.put(playerId, playerInfo);
        logger.info("Player {} (level {}) joined matchmaking queue", playerName, level);
    }
    
    /**
     * 从匹配队列移除玩家
     */
    public void removePlayerFromQueue(long playerId) {
        PlayerQueueInfo playerInfo = waitingPlayers.remove(playerId);
        if (playerInfo != null) {
            logger.info("Player {} left matchmaking queue", playerInfo.getPlayerName());
        }
    }
    
    /**
     * 开始匹配
     */
    public String startMatchmaking(long playerId, Map<String, Object> matchParams) {
        // 从参数中获取玩家信息
        String playerName = (String) matchParams.getOrDefault("playerName", "Player" + playerId);
        int level = (int) matchParams.getOrDefault("level", 1);
        
        // 添加到匹配队列
        addPlayerToQueue(playerId, playerName, level);
        
        // 生成匹配ID
        String matchId = "match_" + playerId + "_" + System.currentTimeMillis();
        logger.info("开始匹配: playerId={}, matchId={}", playerId, matchId);
        return matchId;
    }
    
    /**
     * 取消匹配
     */
    public boolean cancelMatchmaking(long playerId) {
        PlayerQueueInfo playerInfo = waitingPlayers.remove(playerId);
        if (playerInfo != null) {
            logger.info("Player {} canceled matchmaking", playerInfo.getPlayerName());
            return true;
        }
        return false;
    }
    
    /**
     * 获取匹配状态
     */
    public MatchmakingStatus getMatchmakingStatus(long playerId) {
        PlayerQueueInfo playerInfo = waitingPlayers.get(playerId);
        if (playerInfo == null) {
            return new MatchmakingStatus(false, 0, 0);
        }
        
        long waitTime = System.currentTimeMillis() - playerInfo.getQueueTime();
        return new MatchmakingStatus(true, waitingPlayers.size(), waitTime);
    }
    
    /**
     * 匹配状态
     */
    public static class MatchmakingStatus {
        private boolean isInQueue;
        private int queueSize;
        private long waitTime;
        
        public MatchmakingStatus(boolean isInQueue, int queueSize, long waitTime) {
            this.isInQueue = isInQueue;
            this.queueSize = queueSize;
            this.waitTime = waitTime;
        }
        
        // getters
        public boolean isInQueue() {
            return isInQueue;
        }
        
        public int getQueueSize() {
            return queueSize;
        }
        
        public long getWaitTime() {
            return waitTime;
        }
    }
    
    /**
     * 执行匹配逻辑
     */
    @Scheduled(fixedRate = 5000) // 每5秒执行一次匹配
    public void processMatching() {
        if (waitingPlayers.size() < 2) {
            return; // 至少需要2个玩家才能匹配
        }
        
        // 按等级分组匹配
        Map<Integer, List<PlayerQueueInfo>> levelGroups = new HashMap<>();
        for (PlayerQueueInfo player : waitingPlayers.values()) {
            int level = player.getLevelGroup();
            levelGroups.computeIfAbsent(level, k -> new ArrayList<>()).add(player);
        }
        
        // 尝试匹配
        for (List<PlayerQueueInfo> group : levelGroups.values()) {
            if (group.size() >= 2) {
                // 创建匹配结果
                List<PlayerQueueInfo> matchedPlayers = group.subList(0, 2);
                createBattle(matchedPlayers);
                
                // 从队列中移除已匹配的玩家
                for (PlayerQueueInfo player : matchedPlayers) {
                    waitingPlayers.remove(player.getPlayerId());
                }
                
                break; // 本轮只处理一组匹配
            }
        }
    }
    
    /**
     * 创建战斗
     */
    private void createBattle(List<PlayerQueueInfo> players) {
        if (players.size() != 2) {
            logger.warn("创建战斗时玩家数量不为2: {}", players.size());
            return;
        }
        
        PlayerQueueInfo player1 = players.get(0);
        PlayerQueueInfo player2 = players.get(1);
        
        logger.info("匹配成功: {} (等级 {}) vs {} (等级 {})", 
                player1.getPlayerName(), player1.getLevel(),
                player2.getPlayerName(), player2.getLevel());
        
        // 这里应该调用战斗服务创建战斗实例
        // 实际实现中应该调用 BattleMatchManager.createBattle()
    }
    
    /**
     * 获取玩家等级组
     */
    private int getLevelGroup(int level) {
        // 每10级为一个组
        return (level / 10) * 10;
    }
    
    /**
     * 玩家队列信息
     */
    public static class PlayerQueueInfo {
        private long playerId;
        private String playerName;
        private int level;
        private long queueTime;
        
        // getters and setters
        public long getPlayerId() {
            return playerId;
        }
        
        public void setPlayerId(long playerId) {
            this.playerId = playerId;
        }
        
        public String getPlayerName() {
            return playerName;
        }
        
        public void setPlayerName(String playerName) {
            this.playerName = playerName;
        }
        
        public int getLevel() {
            return level;
        }
        
        public void setLevel(int level) {
            this.level = level;
        }
        
        public long getQueueTime() {
            return queueTime;
        }
        
        public void setQueueTime(long queueTime) {
            this.queueTime = queueTime;
        }
        
        public int getLevelGroup() {
            // 每10级为一个组
            return (level / 10) * 10;
        }
    }
}